#include "read_afof.h"
//////////////////////////////////////


CFOFCatalog::CFOFCatalog(string file):m_afofcat(file),RadFrac(1.0)
	{
	  if(m_verbose)
	    cout<<"Reading catalog file :"<<m_afofcat<<endl;
	if(!(m_isgood=ReadCatalog(m_afofcat)))
		{
		cout<<"Cannot open catalog file :"<<m_afofcat<<endl;
		cout<<"Exiting..."<<endl;
		exit(14);
		}


	}
bool CFOFCatalog::ReadCatalogIDsBin(string filename)
	{
	unsigned int nid=0, i=0;

	ifstream ifile(filename.c_str(),ios::in|ios::binary);
	if(	ifile.fail())
		{
		string mes=string("Can not open file: " );
		mes+= filename;
		if(m_verbose)
		  cout<<mes.c_str()<<endl;
		return false;
		}

	ifile.read((char*)(&nid), sizeof(unsigned int));
	vector<unsigned int> grpIDs;
	grpIDs.resize(nid);
	if(m_verbose)
	  cout<<"..";
	ifile.read((char*)(&grpIDs[0]), sizeof(unsigned int)*nid);
	ifile.close();
	////////////////////		
	CGalaxy* gal;
	for(i=0;i<nid;i++)
		{
		if(grpIDs[i] >0)
			{	
			gal=halos[grpIDs[i]];
			gal->idref.push_back(i);
			}
		}
	
	return true;
	}


class CPosDist2comp : public std::binary_function<int,int,bool> 
	{
	const vector<float>	&m_grpIDS;
	public:
		CPosDist2comp( const vector<float> & CgrpIDS ) : m_grpIDS(CgrpIDS) {}
		bool operator()(int a, int b) const
			{
			return (m_grpIDS.at(a)) < (m_grpIDS.at(b));
			}
	};


bool CFOFCatalog::ReadCatalogIDs(string file)
	{

	ifstream file_to_read(file.data());
	//	const int max_num_of_char_in_a_line = 512,// Maximum number of characters expected in a single line in the header
	//	num_of_header_lines = 1; // Number of header files to skip

	if(m_verbose)cout<<"Reading ID file: "<<file;
	if(file_to_read.bad())
		return false;
	int nid=0, i;

	file_to_read>>nid;
	///////////////////////////////
	unsigned int grpIDs=0;
	CGalaxy* gal;
	///////////////////////////////
	for(i=0;i<nid;i++)
		{
		file_to_read>>grpIDs;
		
		if(grpIDs >0)
			{
			gal=halos[grpIDs];
			gal->idref.push_back(i);
			}
		}
	///////////////////////////////
	file_to_read.close();
	return true;


	}

bool CFOFCatalog::ReadCatalog(string file)
	{
	ifstream file_to_read(file.data());
	const int max_num_of_char_in_a_line = 512,// Maximum number of characters expected in a single line in the header
		num_of_header_lines = 1; // Number of header files to skip
	if(m_verbose)
		cout<<"Reading catalog file: "<<file;
	if(file_to_read.bad())
		return false;

	///////////////////////////////
	int Nhalo=0;
	file_to_read.ignore(num_of_header_lines, '#');
	file_to_read>>Nhalo;
	file_to_read.ignore(max_num_of_char_in_a_line, '\n');
	CGalaxy* gal;
	unsigned int grpID=0, tID=0;
	
	for( int ih=0;ih<Nhalo;ih++)
		{
		gal=new CGalaxy;

		file_to_read>>(tID);
		file_to_read>>(grpID);
		file_to_read>>(gal->x[0])>>(gal->x[1])>>(gal->x[2]);

		file_to_read>>(gal->R);
		file_to_read>>(gal->Ntotal);
		file_to_read>>(gal->npart[0])>>(gal->npart[1])>>(gal->npart[2]);
		
		file_to_read.ignore(max_num_of_char_in_a_line, '\n');
		if(!file_to_read.good()){cerr<<"Error reading line in CFOFCatalog::ReadCatalog: FILE= "<<file<<" LINE="<<ih+1<<endl;return false;}
		halos[grpID]=gal;
		}
	///////////////////////////////

	file_to_read.close();
	

	return true;
	}

bool Catvalue_comparer(TGalaxyMap::value_type &i1, TGalaxyMap::value_type &i2)
{
  return i1.second->Ntotal < i2.second->Ntotal;
}

CGalaxy* CFOFCatalog::GetGalByID(unsigned int i)
	{

	TGalaxyMap::iterator itor = std::max_element(halos.begin(), halos.end(),
						     Catvalue_comparer);

	return (*itor).second;
	}


